
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ability_env.h>
#include <ability_manager.h>
#include <file.h>
#include <sys/types.h>
#include <securec.h>

#include "filelist_ability_slice.h"
#include "picture_ability_slice.h"
#include "ui_config.h"
#include "define.h"
#include "file_server.h"

using namespace std;

namespace OHOS {

REGISTER_AS(FileListAbilitySlice)

static void ListViewClear(const UIView *view)
{
    if (view == nullptr || view->IsViewGroup() == false) {
        return;
    }

    UIView *child = static_cast<const UIViewGroup*>(view)->GetChildrenHead();
    UIView *childNext = nullptr;

    while (child != nullptr) {
        childNext = child->GetNextSibling();
        if (child->IsViewGroup()) {
            ListViewClear(child);
        }
        delete child;
        child = childNext;
    }
}

static void DeleteObject(UIView *view)
{
    if (view != nullptr) {
        delete view;
    }
}

FileListAbilitySlice::~FileListAbilitySlice()
{
    if (listView_ != nullptr) {
        ListViewClear(listView_);
        DeleteObject((UIView *)listView_);
    }
    DeleteObject((UIView *)backButton_);
    DeleteObject((UIView *)backArea_);
    DeleteObject((UIView *)background_);
    DeleteObject((UIView *)titleLabel_);
    DeleteObject((UIView *)dialogWin_);
}

static void SetUIRect(UI_RECT *rect, int x, int y, int w, int h)
{
    if (rect == nullptr) {
        return;
    }
    rect->x = x;
    rect->y = y;
    rect->w = w;
    rect->h = h;
}

static bool IsFileType(const char *name, int type)
{
    const int fileTypes = 2;

    const char *g_type[fileTypes] = {
        ".mp4",
        ".jpg"
    };

    if (type >= fileTypes) {
        return false;
    }

    char *ptr = (char *)strrchr(name, '.');
    if (ptr == nullptr) {
        return false;
    }

    return (strcasecmp(g_type[type], ptr) == 0);
}

static UIViewGroup *GetItem(UI_RECT rect, const char *text, UI_RECT textRect, const char *image, UI_RECT imageRect,
                            UIView::OnClickListener *click)
{
    UIViewGroup *group = new UIViewGroup();
    group->SetStyle(STYLE_BACKGROUND_COLOR, 0);
    group->SetPosition(rect.x, rect.y, rect.w, rect.h);
    group->SetTouchable(true);

    UIImageView *itemIcon_ = new UIImageView();
    itemIcon_->SetPosition(imageRect.x, imageRect.y, imageRect.w, imageRect.h);
    itemIcon_->SetSrc(image);
    itemIcon_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    itemIcon_->SetTouchable(true);
    group->Add(itemIcon_);

    UILabel *itemText_ = new UILabel();
    itemText_->SetPosition(textRect.x, textRect.y, textRect.w, textRect.h);
    itemText_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    itemText_->SetFont(FONT_NAME, FONT_SIZE_20);
    itemText_->SetText(text);
    itemText_->SetTouchable(true);
    itemText_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
    group->Add(itemText_);

    group->SetOnClickListener(click);
    itemIcon_->SetOnClickListener(click);
    itemText_->SetOnClickListener(click);

    return group;
}

void FileListAbilitySlice::AddItem(const char *fullPath, int idx)
{
    int x = LISTVIEW_START_X;
    int y = (LINE_HEIGHT + LINE_POS) * idx;
    int w = SCREEN_WIDTH - LISTVIEW_START_X * 2;                      // 2 cups of start x
    int h = LINE_HEIGHT;
    char *name;
    char *sliceName = nullptr;
    char iconPath[256] = {0};
    const char *iconHead = GetSrcPath();
    name = (char *)strrchr(fullPath, '/');
    if (name == nullptr) {
        name = (char *)fullPath;
    } else {
        name++;
    }

    printf("fullPath : %s, name : %s \r\n", fullPath, name);

    if (listType_ == FILE_TYPE_VIDEO) {
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, ICON_VIDEO_PATH_S);
        sliceName = (char *)"PlayerAbilitySlice";
    } else if (listType_ == FILE_TYPE_IMAGE) {
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, iconimage_PATH_S);
        sliceName = (char *)"PictureAbilitySlice";
    } else {
        (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", iconHead, ICON_UNKNOW_PATH);
        sliceName = (char *)"UnknowAbilitySlice";
    }

    UI_RECT mainRect, imageRect, textRect;
    SetUIRect(&mainRect, x, y, w, h);
    SetUIRect(&imageRect, ICON_START_X, ICON_START_Y, ICON_WIDTH, ICON_HEIGHT);
    SetUIRect(&textRect, TEXT_START_X, ICON_START_Y, SCREEN_WIDTH - TEXT_START_X, ICON_HEIGHT);

    HoodsButtonClickListener *itemClick = new HoodsButtonClickListener(this);
    itemClick->SetSliceInfo((const char *)sliceName, (const char *)fullPath);

    UIViewGroup *view = GetItem(mainRect, name, textRect, (const char *)iconPath, imageRect, itemClick);
    listView_->Add(view);
}

void FileListAbilitySlice::GetDeaultListView(int type)
{
    int count = 0;
    DIR *dir;
    struct dirent *entry;
    const char *dirName[] = {
        VIDEO_DEFAULT_PATH,
        IMAGE_DEFAULT_PATH
    };

    if (type < 0 || type > FILE_TYPE_IMAGE) {
        printf("file type OOR! \n");
        return;
    }

    dir = opendir(dirName[type]);
    if (dir == nullptr) {
        return;
    }

    while ((entry = readdir(dir)) != nullptr) {
        if (IsFileType(entry->d_name, listType_)) {
            char fullpath[512] = {0};
            (void)sprintf_s(fullpath, sizeof(fullpath), "%s/%s", dirName, entry->d_name);
            AddItem((const char *)fullpath, count);
            count++;
        }
    }

    closedir(dir);
    dir = nullptr;
}
void FileListAbilitySlice::SetListView(const char *dirName)
{
    int count = 0;
    DIR *dir;
    struct dirent *entry;

    dir = opendir(dirName);
    if (dir == nullptr) {
        return;
    }

    while ((entry = readdir(dir)) != nullptr) {
        if (IsFileType(entry->d_name, listType_)) {
            char fullpath[512] = {0};
            (void)sprintf_s(fullpath, sizeof(fullpath), "%s/%s", dirName, entry->d_name);
            AddItem((const char *)fullpath, count);
            count++;
        }
    }

    closedir(dir);
    dir = nullptr;
}

void FileListAbilitySlice::SetHead()
{
    const char *title[] = {
        "视频",
        "图片"
    };
    char iconPath[256] = {0};
    const char *pHead = GetSrcPath();
    (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", pHead, LISTVIEW_BACKGROUND);

    background_ = new UIImageView();
    background_->SetPosition(START_XPOS, START_YPOS, SCREEN_WIDTH, SCREEN_HEIGHT);
    background_->SetSrc((char *)iconPath);
    background_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    rootView_->Add(background_);

    memset(iconPath, 0x00, sizeof(iconPath));
    (void)sprintf_s(iconPath, sizeof(iconPath), "%s/%s", pHead, ICON_BACK0_PATH);
    backButton_ = new UIImageView();
    backButton_->SetPosition(BACK_ICON_XPOS, BACK_ICON_YPOS, BACK_ICON_WIDTH, BACK_ICON_HEIGHT);
    backButton_->SetSrc((char *)iconPath);
    backButton_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    backButton_->SetTouchable(true);
    rootView_->Add(backButton_);

    HoodsButtonClickListener *click = new HoodsButtonClickListener(this);
    click->SetSliceInfo("HoodsAbilitySlice", nullptr);
    backButton_->SetOnClickListener(click);

    backArea_ = new UIImageView();
    backArea_->SetPosition(0, 0, TITLE_HEIGHT, TITLE_HEIGHT);
    backArea_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    backArea_->SetTouchable(true);
    backArea_->SetOnClickListener(click);
    rootView_->Add(backArea_);

    titleLabel_ = new UILabel();
    titleLabel_->SetPosition(TITLE_XPOS, TITLE_YPOS, TITLE_WIDTH, TITLE_HEIGHT);
    titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,
                          UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
    titleLabel_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    titleLabel_->SetFont(FONT_NAME, FONT_SIZE_32);
    titleLabel_->SetText((char *)title[listType_]);
    titleLabel_->SetTouchable(true);
    titleLabel_->SetOnClickListener(click);
    rootView_->Add(titleLabel_);
}

int FileListAbilitySlice::DialogDisplay(const char *msg, int type, int timeout)
{
    int result = 0;
    int tmCnt = 0;

    dialogWin_->Display(msg, type, timeout);

    while (true) {
        result = dialogWin_->GetResult();
        if (result != -1) {
            break;
        }
        sleep(1);

        if (timeout > 0 && ++tmCnt >= timeout) {
            result = 0;
            break;
        }
    }

    return result;
}

static int ShowDialog(void *data, const char *msg, DIALOG_TYPE type, int timeout)
{
    FileListAbilitySlice *fileList = (FileListAbilitySlice *)data;
    if (fileList == nullptr) {
        return 0;
    }

    return fileList->DialogDisplay(msg, type, timeout);
}

void FileListAbilitySlice::OnStart(const Want &want)
{
    AbilitySlice::OnStart(want);
    char *data = reinterpret_cast<char*>(want.data);
    if (strcasecmp(data, "video") == 0) {
        listType_ = FILE_TYPE_VIDEO;
    } else {
        listType_ = FILE_TYPE_IMAGE;
    }

    rootView_ = RootView::GetWindowRootView();
    rootView_->SetPosition(START_XPOS, START_YPOS, SCREEN_WIDTH, SCREEN_HEIGHT);
    rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);

    SetHead();

    listView_ = new UIScrollView();
    listView_->SetPosition(0, TITLE_HEIGHT + 1, SCREEN_WIDTH, SCREEN_HEIGHT - TITLE_HEIGHT);
    listView_->SetStyle(STYLE_BACKGROUND_OPA, 0);
    listView_->SetXScrollBarVisible(true);
    listView_->SetYScrollBarVisible(true);
    listView_->SetTouchable(true);
    rootView_->Add(listView_);
    GetDeaultListView(listType_);
    if (listType_ == FILE_TYPE_VIDEO) {
        SetListView(VIDEO_DEFAULT_PATH);
    } else {
        SetListView(IMAGE_DEFAULT_PATH);
    }
    SetListView(RECV_FILE_PATH);

    dialogWin_ = new PopupDialog();
    dialogWin_->Create(rootView_, POP_WIN_X, POP_WIN_Y, POP_WIN_W, POP_WIN_H);

    SetUIContent(rootView_);
    rootView_->Invalidate();
}

void FileListAbilitySlice::OnInactive()
{
    AbilitySlice::OnInactive();
}

void FileListAbilitySlice::OnActive(const Want &want)
{
    AbilitySlice::OnActive(want);
    FileServerSetDialog(ShowDialog, this);
}

void FileListAbilitySlice::OnBackground()
{
    AbilitySlice::OnBackground();
}

void FileListAbilitySlice::OnStop()
{
    AbilitySlice::OnStop();
}

}
